package com.smsc.headend.task.engine.executor;

import cn.hutool.json.JSONUtil;
import com.smsc.headend.module.asset.entity.Meter;
import com.smsc.headend.module.task.dto.AtomicTask;
import com.smsc.headend.module.task.dto.SubTaskGroup;
import com.smsc.headend.module.task.dto.Task;
import com.smsc.headend.task.engine.exception.UDISTaskExecutorException;
import com.smsc.headend.module.task.dto.AtomicTaskState;
import com.smsc.headend.task.engine.service.asset.AssetService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

public interface TaskExecutor {

    Logger log = LoggerFactory.getLogger(TaskExecutor.class);

    AtomicTaskState execute(Task task, AtomicTask atomicTask) throws UDISTaskExecutorException;

    default Map<String, Object> getParameterMap(Task task, AtomicTask atomicTask) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("atomicTask", atomicTask);
        if (StringUtils.isNotEmpty(task.getParamJson())) {
            paramMap.putAll(JSONUtil.toBean(task.getParamJson(), Map.class));
        }
        if (StringUtils.isNotEmpty(atomicTask.getAtomicTaskParam())) {
            paramMap.putAll(JSONUtil.toBean(atomicTask.getAtomicTaskParam(), Map.class));
        }
        return paramMap;
    }

    default Meter getMeter(Task task, AssetService assetService) {
        return task.getMeterId() == null ? null : assetService.getMeterById(task.getMeterId());
    }

    default AtomicTaskState createAtomicState(Class handlerClass) {
        AtomicTaskState atomicTaskState = new AtomicTaskState();
        atomicTaskState.setHandlerClass(handlerClass == null ? null : handlerClass.getName());
        return atomicTaskState;
    }

    default Boolean handleFailure(Task task, AtomicTask atomicTask, String message) {
        log.warn("{} is not implement failure handle method", this.getClass());
        return true;
    }

    default boolean isSubTaskGroupFirstAtomicTask(Task task, AtomicTask atomicTask){
        for (SubTaskGroup g : task.getSubTaskGroups()) {
            if (g.getSubTasks().get(0).getAtomicTaskNo().equalsIgnoreCase(atomicTask.getAtomicTaskNo())) {
                return true;
            }
        }
        return false;
    }

    default boolean isSubTaskGroupLastAtomicTask(Task task, AtomicTask atomicTask){
        for (SubTaskGroup g : task.getSubTaskGroups()) {
            if (g.getSubTasks().get(g.getSubTasks().size() - 1).getAtomicTaskNo().equalsIgnoreCase(atomicTask.getAtomicTaskNo())) {
                return true;
            }
        }
        return false;
    }
}
